#include "section.h"
#include "stdio.h"
#include "string.h"

/* log output control */
#define DBG_ENABLE
#define DBG_SECTION_NAME "section"
#define DBG_LEVEL DBG_LOG
#define DBG_COLOR
#include "rtdbg.h"

static void rti_start(void) /* first pile */
{
}
INIT_EXPORT(rti_start, "0");

static void rti_board_start(void)
{
}
INIT_EXPORT(rti_board_start, "0.end");

static void rti_board_end(void)
{
}
INIT_EXPORT(rti_board_end, "1.end");
static void rti_end(void) /* end pile */
{
}
INIT_EXPORT(rti_end, "6.end");
static void rti_run_section(void) /* end pile */
{
}
INIT_EXPORT(rti_run_section, "7.end");


void components_init(void)
{
#if RT_DEBUG_INIT
    unsigned char cnt = 0 ;
    const struct rt_init_desc *desc;
    for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_end; desc ++)
    {
        rt_kprintf("%-2d init %s\r\n", ++cnt, desc->fn_name);
        desc->fn();
    }
#else
    const init_fn_t *fn_ptr;
    for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_end; fn_ptr++)
    {
        (*fn_ptr)();
    }
#endif
}
#if RT_DEBUG_INIT
void show_components_run(void)
{
    unsigned char cnt = 0 ;
    const struct rt_init_desc *desc;
    rt_kprintf("\r\n\r\n");
    for (desc = &__rt_init_desc_rti_end, desc++ ; desc < &__rt_init_desc_rti_run_section; desc++)
    {
        rt_kprintf("%-2d run %s\r\n", ++cnt, desc->fn_name);
    }
    rt_kprintf("\r\n");
}
INIT_APP_EXPORT(show_components_run);
#endif

void components_run(void)
{
#if RT_DEBUG_INIT
    const struct rt_init_desc *desc;
    for (desc = &__rt_init_desc_rti_end, desc++; desc < &__rt_init_desc_rti_run_section; desc ++)
    {
        desc->fn();
    }
#else
    /* can not out to log */
    const init_fn_t *fn_ptr = &__rt_init_rti_end;
    fn_ptr++;
    for (; fn_ptr < &__rt_init_rti_run_section; fn_ptr++)
    {
        (*fn_ptr)();
    }
#endif
}

void components_run_normal(void)
{
#if RT_DEBUG_INIT
    static const struct rt_init_desc *desc = &__rt_init_desc_rti_end ;
    if (++desc < &__rt_init_desc_rti_run_section)
    {
        desc->fn();
    }
    else
    {
        desc = &__rt_init_desc_rti_end;
    }
#else
    static const init_fn_t *fn_ptr = &__rt_init_rti_end; /* first run can rti_end and after is not run */
    if (++fn_ptr < &__rt_init_rti_run_section)
    {
        (*fn_ptr)();
    }
    else
    {
        fn_ptr = &__rt_init_rti_end;
    }
#endif
}


/**
 * The RT_ASSERT function.
 *
 * @param ex the assertion condition string
 * @param func the function name when assertion.
 * @param line the file line number when assertion.
 */
void rt_assert_handler(const char *ex_string, const char *func, unsigned short line)
{
    unsigned short cnt = 0;
	volatile char dummy = 0;

    while (dummy == 0)
	{
		if ( cnt == 0 )
		{
			rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex_string, func, line);
		}
		cnt++;
	}
}



